package service

import (
	"context"
	"encoding/json"
	"github.com/gorilla/websocket"
	"github.com/star-find-cloud/star-chat/ErrorCode"
	ws "github.com/star-find-cloud/star-chat/internal/websocket"
	"github.com/star-find-cloud/star-chat/message/domain"
	"github.com/star-find-cloud/star-chat/pkg/idgen"
	log "github.com/star-find-cloud/star-chat/pkg/logger"
	"time"
)

type ServiceImpl struct {
	repo      domain.Repo
	wsManager *ws.ConnectManager
}

func NewService(repo domain.Repo) domain.Service {
	return &ServiceImpl{repo: repo}
}

func (s *ServiceImpl) Send(ctx context.Context, messageChan chan *domain.Message) error {
	message := <-messageChan
	if message.IsToAndFromEmpty() {
		return ErrorCode.ERROR_Code_Check_IsEmpty
	}
	uid, err := idgen.GetUidGenerator().GetUid(ctx)
	if err != nil {
		log.AppLogger.Errorf("生成uid失败, err:%v", err)
		return ErrorCode.ERROR_Code_Server_Busy
	}
	message.ID = uid
	err = s.repo.Upload(ctx, message)
	if err != nil {
		log.AppLogger.Errorf("上传消息失败, err:%v", err)
		return ErrorCode.ERROR_Code_Server_Busy
	}

	msgData, err := json.Marshal(message)
	if err != nil {
		log.AppLogger.Errorf("序列化消息失败, err:%v", err)
		return ErrorCode.ERROR_Code_Server_Busy
	}

	sendMessage := &ws.Message{
		WebSocketType: websocket.TextMessage,
		MessageType:   ws.MessageTypeNormal,
		Data:          msgData,
		Time:          time.Now(),
		MsgID:         uid,
		Target:        message.ToID,
	}
	err = s.wsManager.SendToUser(message.ToID, sendMessage)
	if err != nil {
		log.AppLogger.Errorf("发送消息失败, err:%v", err)
		return ErrorCode.ERROR_Code_WS_SendMessageError
	}

	return nil
}

func (s *ServiceImpl) FindMsgByUser(ctx context.Context, fromID, toID int) (*[]domain.Message, error) {
	if fromID == 0 || toID == 0 {
		return nil, ErrorCode.ERROR_Code_Check_IsEmpty
	}
	if fromID == toID {
		return nil, ErrorCode.ERROR_Code_Check_IsSame
	}
	if fromID < 0 || toID < 0 {
		return nil, ErrorCode.ERROR_Code_Invalid
	}
	msg, err := s.repo.GetByUserID(ctx, fromID, toID)
	if err != nil {
		log.AppLogger.Errorf("获取消息失败, err:%v", err)
		return nil, ErrorCode.ERROR_Code_Server_Busy
	}
	return msg, nil
}

func (s *ServiceImpl) FindMsgByText(ctx context.Context, msg string, userid int) (*[]domain.Message, error) {
	if msg == "" || userid == 0 {
		return nil, ErrorCode.ERROR_Code_Check_IsEmpty
	}
	if userid < 0 {
		return nil, ErrorCode.ERROR_Code_Invalid
	}

	message, err := s.repo.GetByMsg(ctx, msg, userid)
	if err != nil {
		log.AppLogger.Errorf("获取消息失败, err:%v", err)
		return nil, ErrorCode.ERROR_Code_Server_Busy
	}
	return message, nil
}

func (s *ServiceImpl) Delete(ctx context.Context, messageId int64) error {
	if messageId <= 0 {
		return ErrorCode.ERROR_Code_Invalid
	}

	err := s.repo.Delete(ctx, messageId)
	if err != nil {
		log.AppLogger.Errorf("删除消息失败, err:%v", err)
		return ErrorCode.ERROR_Code_Server_Busy
	}
	return nil
}
